package com.meta.platform.contract.domain.aggr;

import com.meta.framework.common.utils.SecurityUtils;
import com.meta.platform.contract.intf.cmd.contractplanfund.AddContractPlanFundCmd;
import com.meta.platform.contract.intf.cmd.contractplanfund.UpdateContractPlanFundCmd;
import com.meta.platform.contract.intf.entity.ContractPlanFund;
import com.meta.platform.contract.intf.enums.PlanFundStatusEnum;
import lombok.Data;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;


@Data
public class ContractPlanFundDo extends ContractPlanFund {

    public static ContractPlanFundDo of(ContractPlanFund crmContractPlanFund){
        if (crmContractPlanFund == null){
            return null;
        }
        ContractPlanFundDo planFundDo = new ContractPlanFundDo();
        BeanUtils.copyProperties(crmContractPlanFund, planFundDo);

        return planFundDo;
    }

    public static List<ContractPlanFundDo> of(List<ContractPlanFund> crmContractPlanFunds){

        if (CollectionUtils.isEmpty(crmContractPlanFunds)){
            return new ArrayList<>();
        }

        List<ContractPlanFundDo> resList = new ArrayList<>();
        for (ContractPlanFund entity : crmContractPlanFunds) {
            resList.add(ContractPlanFundDo.of(entity));
        }

        return resList;
    }

    public static ContractPlanFundDo create(AddContractPlanFundCmd contractPlanFund){
        if (contractPlanFund == null){
            return null;
        }
        ContractPlanFundDo planFundDo = new ContractPlanFundDo();
        BeanUtils.copyProperties(contractPlanFund, planFundDo);

        planFundDo.setPlanFundStatus(PlanFundStatusEnum.NONE.getCode());

        return planFundDo;
    }

    public void update(UpdateContractPlanFundCmd updateContractPlanFundCmd){
        Long id = this.getId();
        BeanUtils.copyProperties(updateContractPlanFundCmd, this);
        this.setId(id);

        updateStatus();
    }

    public void updateStatusAndActualAmount(List<ContractFundRecordDo> recordDos){
        if (CollectionUtils.isEmpty(recordDos)){
            this.setPlanFundStatus(PlanFundStatusEnum.NONE.getCode());
            return;
        }

        BigDecimal totalAmount = new BigDecimal(0);

        for (ContractFundRecordDo recordDo : recordDos) {
            BigDecimal amount = recordDo.getActualFundAmount();
            if (amount != null){
                totalAmount = totalAmount.add(amount);
            }
        }

        totalAmount = totalAmount.setScale(2, RoundingMode.FLOOR);
        this.setActualAmount(totalAmount);

        updateStatus();
    }

    private void updateStatus(){
        //状态变更
        BigDecimal totalAmount = this.getActualAmount().setScale(2, RoundingMode.FLOOR);
        BigDecimal plan = this.getPlanFundAmount().setScale(2, RoundingMode.FLOOR);
        BigDecimal zero = new BigDecimal(0).setScale(2,RoundingMode.FLOOR);

        if (totalAmount.compareTo(plan) >= 0 || (totalAmount.equals(zero) && plan.equals(zero))){
            this.setPlanFundStatus(PlanFundStatusEnum.COMPLETE.getCode());
        }
        else if (totalAmount.equals(zero)){
            this.setPlanFundStatus(PlanFundStatusEnum.NONE.getCode());
        }
        else{
            this.setPlanFundStatus(PlanFundStatusEnum.PART.getCode());
        }
    }

}
